﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using System.Text.RegularExpressions;
using System.Collections;
using Slam.SharePoint;

namespace SlamCms.SharePoint.SlamProfiles.ContentItem
{
	public static class SPListItemExtender
	{
		private static Regex tokenFormat = new Regex("(?<={)([^/]*)(?=})", RegexOptions.Compiled);

		public static string FormatFrontEndUrl(this SPListItem listItem, string urlFormat, ContentItemConfiguredType contentItemType)
		{
			Dictionary<string, string> replacements = new Dictionary<string, string>();
			if (!contentItemType.AllowFrontEndUrlCharacters.Contains("/"))
			{
				replacements.Add("/", "~");
			}
			if (!contentItemType.AllowFrontEndUrlCharacters.Contains("&"))
			{
				replacements.Add("&", "");
			}
			if (!contentItemType.AllowFrontEndUrlCharacters.Contains(" "))
			{
				replacements.Add(" ", "-");
			}

			string returnUrl = urlFormat;

			bool versioningEnabled = listItem.ParentList.EnableModeration && listItem.ParentList.EnableVersioning;

			foreach (Match matchedToken in tokenFormat.Matches(urlFormat))
			{
				string replaceValue = "";
				if (matchedToken.Value.Equals("wiki page", StringComparison.OrdinalIgnoreCase))
				{
					replaceValue = listItem.Web.ServerRelativeUrl.TrimStart('/').TrimEnd('/') + "/" + listItem["Name"].ToString().Trim();
					foreach (KeyValuePair<string, string> replacement in replacements)
					{
						replaceValue = replaceValue.Replace(replacement.Key, replacement.Value);
					}
				}
				else if (listItem.Fields.ContainsField(matchedToken.Value) && listItem[matchedToken.Value] != null && !String.IsNullOrEmpty(Convert.ToString(listItem[matchedToken.Value])))
				{
					replaceValue = listItem[matchedToken.Value].ToString().Trim();
					foreach (KeyValuePair<string, string> replacement in replacements)
					{
						replaceValue = replaceValue.Replace(replacement.Key, replacement.Value);
					}
				}
				else if (matchedToken.Value.Equals("Title"))
				{
					replaceValue = listItem.GetTitle().Trim();
					foreach (KeyValuePair<string, string> replacement in replacements)
					{
						replaceValue = replaceValue.Replace(replacement.Key, replacement.Value);
					}
				}

				if (versioningEnabled && matchedToken.Value.Equals("SLAM ID", StringComparison.CurrentCultureIgnoreCase))
				{
					replaceValue = Regex.Replace(replaceValue, "-p", "");
				}

				if (!String.IsNullOrEmpty(replaceValue))
				{
					returnUrl = returnUrl.Replace(String.Format("{{{0}}}", matchedToken.Value), Regex.Replace(replaceValue, @"[^\w\-\+\~\/\&\s]", ""));
				}
			}

			return returnUrl;
		}

		public static int GetLiveVersionId(this SPListItem listItem)
		{
			int liveVersionId = 0;
			if (listItem.Fields.ContainsField(ContentItemFieldIdentifier.LiveVersionIdInternalName) && listItem[ContentItemFieldIdentifier.LiveVersionIdInternalName] != null)
			{
				liveVersionId = Int32.Parse(listItem[ContentItemFieldIdentifier.LiveVersionIdInternalName].ToString());
				if (listItem.Versions.GetVersionFromID(liveVersionId).Level != SPFileLevel.Published)
				{
					liveVersionId = 0;
				}
			}

			if (liveVersionId == 0 && listItem.ParentList.EnableVersioning && listItem["UniqueId"] != null)
			{
				for (int i = 0; i < listItem.Versions.Count; i++)
				{
					if (listItem.Versions[i].Level == SPFileLevel.Published)
					{
						liveVersionId = listItem.Versions[i].VersionId;
						break;
					}
				}
			}

			return liveVersionId;
		}

		public static void SetLiveVersionId(this SPListItem listItem)
		{
			if (!listItem.Fields.ContainsField(ContentItemFieldIdentifier.LiveVersionIdInternalName))
			{
				SPWeb web = listItem.Web;
				SPList parentList = web.Lists[listItem.ParentList.ID];
				SPField newField = parentList.Fields.CreateNewField("Text", ContentItemFieldIdentifier.LiveVersionIdInternalName);
				newField.Hidden = true;
				parentList.Fields.Add(newField);
				web.AllowUnsafeUpdates = true;
				parentList.Update();
			}

			listItem.Web.AllowUnsafeUpdates = true;
			listItem[ContentItemFieldIdentifier.LiveVersionIdInternalName] = listItem.Versions[0].VersionId;
			listItem.SystemUpdate(false);
		}

		public static string GetPublishingStatus(this SPListItem listItem)
		{
			string status = "";
			if (listItem.Fields.ContainsField(ContentItemFieldIdentifier.PublishingStatusDisplayName) && listItem[ContentItemFieldIdentifier.PublishingStatusDisplayName] != null)
			{
				status = listItem[ContentItemFieldIdentifier.PublishingStatusDisplayName].ToString();
			}
			return status;
		}

		public static void SetPublishingStatus(this SPListItem listItem)
		{
			SPList list = listItem.ParentList;

			Guid approvalFeatureId = new Guid("2a9ce9d9-4d76-439a-aef2-a28153f03688");
			bool approvalEnabled = list.ParentWeb.Site.Features.Any(f => f.DefinitionId.Equals(approvalFeatureId));

			string status = ContentItemStatus.New.Name;

			if (list.EnableModeration && list.EnableVersioning)
			{
				string submittedForApproval = listItem.GetSlamPropertyValue("SubmitItemForApproval");
				if (approvalEnabled && listItem.ModerationInformation.Status == SPModerationStatusType.Pending && !String.IsNullOrEmpty(submittedForApproval) && bool.Parse(submittedForApproval))
				{
					status = listItem.HasPublishedVersion ? ContentItemStatus.PendingApprovalModified.Name : ContentItemStatus.PendingApprovalNew.Name;
				}
				else if (listItem.ModerationInformation.Status == SPModerationStatusType.Denied)
				{
					status = ContentItemStatus.Retired.Name;
				}
				else if (listItem.HasPublishedVersion)
				{
					if (listItem.Versions[0].Level == SPFileLevel.Published)
					{
						status = ContentItemStatus.Live.Name;
					}
					else
					{
						status = ContentItemStatus.Modified.Name;
					}
				}
			}
			else
			{
				status = ContentItemStatus.Live.Name;
			}

			listItem.Web.AllowUnsafeUpdates = true;
			listItem[ContentItemFieldIdentifier.PublishingStatusDisplayName] = status;
			listItem.SystemUpdate(false);
		}
	}
}
